package uk.co.droidinactu.sony.prst1.home.view;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import uk.co.droidinactu.sony.prst1.home.R;
import uk.co.droidinactu.sony.prst1.home.data.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.TextView;

public final class ApplicationsActivity extends AbstractListActivity implements OnItemClickListener {

    /**
     * GridView adapter to show the list of all installed applications.
     */
    public class ApplicationsAdapter extends ArrayAdapter<Application> {
        private final Rect mOldBounds = new Rect();

        public ApplicationsAdapter(final Context context, final ArrayList<Application> apps) {
            super(context, 0, apps);
        }

        @Override
        public View getView(final int position, View convertView, final ViewGroup parent) {
            final Application info = mApplications.get(position);

            if (convertView == null) {
                final LayoutInflater inflater = getLayoutInflater();
                convertView = inflater.inflate(R.layout.application, parent, false);
            }

            Drawable icon = info.icon;

            if (!info.filtered) {
                int width = 100;
                int height = 100;

                final int iconWidth = icon.getIntrinsicWidth();
                final int iconHeight = icon.getIntrinsicHeight();

                if (icon instanceof PaintDrawable) {
                    final PaintDrawable painter = (PaintDrawable) icon;
                    painter.setIntrinsicWidth(width);
                    painter.setIntrinsicHeight(height);
                }

                if ((width > 0) && (height > 0) && ((width < iconWidth) || (height < iconHeight))) {
                    final float ratio = (float) iconWidth / iconHeight;

                    if (iconWidth > iconHeight) {
                        height = (int) (width / ratio);
                    } else if (iconHeight > iconWidth) {
                        width = (int) (height * ratio);
                    }

                    final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                            : Bitmap.Config.RGB_565;
                    final Bitmap thumb = Bitmap.createBitmap(width, height, c);
                    final Canvas canvas = new Canvas(thumb);
                    canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, 0));

                    // Copy the old bounds to restore them later If we were to do oldBounds =
                    // icon.getBounds(), the call to setBounds() that follows would change the same
                    // instance and we would lose the old bounds
                    mOldBounds.set(icon.getBounds());
                    icon.setBounds(0, 0, width, height);
                    icon.draw(canvas);
                    icon.setBounds(mOldBounds);
                    icon = info.icon = new BitmapDrawable(thumb);
                    info.filtered = true;
                }
            }

            final TextView textView = (TextView) convertView.findViewById(R.id.label);
            textView.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null);
            textView.setText(info.title);

            return convertView;
        }
    }

    private GridView mAppGrid;
    private ArrayList<Application> mApplications;

    /**
     * Loads the list of installed applications in mApplications.
     */
    private void loadApplications() {
        if (mApplications != null) { return; }

        final PackageManager manager = getPackageManager();

        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);
        Collections.sort(apps, new ResolveInfo.DisplayNameComparator(manager));

        if (apps != null) {
            final int count = apps.size();

            if (mApplications == null) {
                mApplications = new ArrayList<Application>(count);
            }
            mApplications.clear();

            for (int i = 0; i < count; i++) {
                final Application application = new Application();
                final ResolveInfo info = apps.get(i);

                application.title = info.loadLabel(manager);
                application.setActivity(new ComponentName(info.activityInfo.applicationInfo.packageName,
                        info.activityInfo.name), Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
                application.icon = info.activityInfo.loadIcon(manager);

                mApplications.add(application);
            }

            mAppGrid.setAdapter(new ApplicationsAdapter(this, mApplications));
            mAppGrid.setSelection(0);
        }
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.apps_grid);

        mAppGrid = (GridView) findViewById(R.id.apps_grid);
        mAppGrid.setVisibility(View.VISIBLE);
        mAppGrid.setOnItemClickListener(this);

        loadApplications();
    }

    @Override
    public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
        final Application app = (Application) parent.getItemAtPosition(position);
        startActivity(app.intent);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

}
